﻿using CleanLite.Domain.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;

namespace CleanLite.Web.Filters
{
    public class GlobalApiResponseFilter : IAsyncResultFilter
    {
        public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next)
        {
            if (context.Result is ObjectResult objectResult)
            {
                if (objectResult.Value is ApiResponse)
                {
                    await next();
                    return;
                }
                // 包装原始数据
                var wrappedResult = ApiResponse<object>.SuccessResponse(objectResult.Value??string.Empty);

                // 更新结果
                context.Result = new ObjectResult(wrappedResult)
                {
                    StatusCode = objectResult.StatusCode ?? 200 // 保持原始状态码
                };
            }
            else if (context.Result is EmptyResult) // 处理 void 或 Task 的情况
            {
                context.Result = new ObjectResult(ApiResponse.SuccessResponse())
                {
                    StatusCode = 200
                };
            }
            else if (context.Result is BadRequestObjectResult badRequestResult)
            {
                var wrappedResult = ApiResponse<object>.FailResponse(badRequestResult.Value ?? string.Empty, badRequestResult?.Value?.ToString() ?? "请求无效");
                context.Result = new ObjectResult(wrappedResult) { StatusCode = 400 };
            }
            else if (context.Result is ForbidResult || context.Result is UnauthorizedResult)
            {
                var wrappedResult = ApiResponse.FailResponse("未授权或禁止访问");
                context.Result = new ObjectResult(wrappedResult) { StatusCode = 401 };
            }
            else if (context.Result is StatusCodeResult codeResult && codeResult.StatusCode >= 400)
            {
                context.Result = new ObjectResult(ApiResponse.FailResponse($"请求失败，状态码：{codeResult.StatusCode}"))
                {
                    StatusCode = codeResult.StatusCode
                };
            }

            await next();
        }
    }
}